Take cursor hotspot from pixbuf if available
authorChristian Persch <chpe@gnome.org>
Fri, 15 Oct 2010 18:34:44 +0000 (14:34 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 15 Oct 2010 18:38:21 +0000 (14:38 -0400)
Allow -1 for the hotspot coordinates in gdk_cursor_new_from_pixbuf,
if the pixbuf contains the x_hot/y_hot options with appropriate values.

Bug #632140.

gdk/x11/gdkcursor-x11.c

index 6808c0e0e95eb586065b44e43ba2765c446c78c0..6fddde869c2494cbb7ac6e124e344b854c209e8a 100644 (file)
@@ -44,6 +44,7 @@
 #include <X11/extensions/Xfixes.h>
 #endif
 #include <string.h>
+#include <errno.h>
 
 
 static guint theme_serial = 0;
@@ -641,6 +642,11 @@ create_cursor_image (GdkPixbuf *pixbuf,
  * gdk_display_get_maximal_cursor_size() give information about 
  * cursor sizes.
  *
+ * If @x or @y are <literal>-1</literal>, the pixbuf must have
+ * options named "x_hot" and "y_hot", resp., containing
+ * integer values between %0 and the width resp. height of
+ * the pixbuf. (Since: 3.0)
+ *
  * On the X backend, support for RGBA cursors requires a
  * sufficently new version of the X Render extension. 
  *
@@ -658,9 +664,34 @@ gdk_cursor_new_from_pixbuf (GdkDisplay *display,
   Cursor xcursor;
   GdkCursorPrivate *private;
   GdkCursor *cursor;
+  const char *option;
+  char *end;
+  gint64 value;
 
   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
   g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+  if (x == -1 && (option = gdk_pixbuf_get_option (pixbuf, "x_hot")))
+    {
+      errno = 0;
+      end = NULL;
+      value = g_ascii_strtoll (option, &end, 10);
+      if (errno == 0 &&
+          end != option &&
+          value >= 0 && value < G_MAXINT)
+        x = (gint) value;
+    }
+  if (y == -1 && (option = gdk_pixbuf_get_option (pixbuf, "y_hot")))
+    {
+      errno = 0;
+      end = NULL;
+      value = g_ascii_strtoll (option, &end, 10);
+      if (errno == 0 &&
+          end != option &&
+          value >= 0 && value < G_MAXINT)
+        y = (gint) value;
+    }
+
   g_return_val_if_fail (0 <= x && x < gdk_pixbuf_get_width (pixbuf), NULL);
   g_return_val_if_fail (0 <= y && y < gdk_pixbuf_get_height (pixbuf), NULL);